package com.qike.baoxiu.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.Gson;
import com.qike.baoxiu.controller.NewOrderSocket;
import com.qike.baoxiu.dto.*;
import com.qike.baoxiu.enums.*;
import com.qike.baoxiu.mapper.*;
import com.qike.baoxiu.pojo.*;
import com.qike.baoxiu.service.OrderService;
import com.qike.baoxiu.tools.OrderNoUtil;
import com.qike.baoxiu.tools.TimeTool;
import com.qike.baoxiu.tools.TokenUtil;
import com.qike.baoxiu.vo.*;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import io.swagger.annotations.ApiModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.MethodWrapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.*;

/**
 * @program: baoxiu
 * @author: Eric
 * @create: 2020-06-01 15:30
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private BaoxiuOrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrderPhotoMapper orderPhotoMapper;
    @Autowired
    private UserDeviceMapper userDeviceMapper;
    @Autowired
    private KnowledgeMapper knowledgeMapper;
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private MessageService messageService;
    @Autowired
    private OrderFixMapper orderFixMapper;
    @Autowired
    private DirectoryMapper directoryMapper;
    @Autowired
    private MonthReportMapper  monthReportMapper;

    /**
     * 订单统计
     *
     * @return
     */
    @Override
    public OrderCountVo OrderCount() {
        Integer id = TokenUtil.getTokenUserId();
        OrderCountVo vo = new OrderCountVo();
        //今日已完成
        BaoxiuOrderExample orderExample = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = orderExample.createCriteria().andAddTimeBetween(TimeTool.getDayBegin(), TimeTool.getDayEnd()).andOrderStatusEqualTo(2);
        if (id != null&&id!=1) {
            criteria.andFixIdEqualTo(id);
        }
        List<BaoxiuOrder> fOrders = orderMapper.selectByExample(orderExample);
        //今日待完成
        List<Integer> uf = new ArrayList<>();
        uf.add(0);
        uf.add(1);
        orderExample.clear();
        orderExample.createCriteria().andAddTimeBetween(TimeTool.getDayBegin(), TimeTool.getDayEnd()).andOrderStatusIn(uf);
        List<BaoxiuOrder> ufOrders = orderMapper.selectByExample(orderExample);
        //今日总数
        List<Integer> TodayAll = new ArrayList<>();
        TodayAll.add(0);
        TodayAll.add(1);
        TodayAll.add(2);
        orderExample.clear();
        orderExample.createCriteria().andAddTimeBetween(TimeTool.getDayBegin(), TimeTool.getDayEnd()).andOrderStatusIn(TodayAll);
        List<BaoxiuOrder> TodayOrders = orderMapper.selectByExample(orderExample);
        //累计完成
        orderExample.clear();
        orderExample.createCriteria().andOrderStatusEqualTo(2);
        List<BaoxiuOrder> AllFinish = orderMapper.selectByExample(orderExample);
        vo.setTodayFinish(fOrders.size());
        vo.setTodayTotal(TodayOrders.size());
        vo.setTodayUnFinish(ufOrders.size());
        vo.setTotal(AllFinish.size());
        //当月完成数
        orderExample.clear();
        Date beginDayOfMonth = TimeTool.getBeginDayOfMonth();
        Date endDayOfMonth = TimeTool.getEndDayOfMonth();
        orderExample.createCriteria().andOrderStatusEqualTo(2).andFinishTimeBetween(beginDayOfMonth,endDayOfMonth);
        List<BaoxiuOrder> totalMonth = orderMapper.selectByExample(orderExample);
        vo.setMonthTotal(totalMonth.size());
        return vo;
    }

    /**
     * 维修单列表
     *
     * @param orderListDto
     * @return
     */
    @Override
    public OrderListVo orderList(OrderListDto orderListDto) {
        Integer userId = TokenUtil.getTokenUserId();
        System.out.println("uid="+userId);
//        User user = userMapper.selectByPrimaryKey(userId);
        OrderListVo vo = new OrderListVo();
        List<OrderVo> list = new ArrayList<>();
        BaoxiuOrderExample orderExample = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = orderExample.createCriteria();
        if (orderListDto.getFixId() != null) {
            criteria.andFixIdEqualTo(orderListDto.getFixId());
        }
//        if (user != null && user.getRole().equals(1) && !orderListDto.getOrderStatus().equals(OrderStatusEnums.UN_TAKE.getEcode())) {
//        if (user != null && user.getRole().equals(1)) {
//            criteria.andFixIdEqualTo(user.getId());
//        }
          if (orderListDto.getType() != null) {
            criteria.andTypeEqualTo(orderListDto.getType());
        }
        if (orderListDto.getOrderStatus() != null) {
            criteria.andOrderStatusEqualTo(orderListDto.getOrderStatus());
        }
        if (orderListDto.getBegin() != null && orderListDto.getEnd() != null) {
            Date begin = new Date(orderListDto.getBegin());
            Timestamp dayStartTime = TimeTool.getDayStartTime(begin);
            Date end = new Date(orderListDto.getBegin());
            Timestamp dayEndTime = TimeTool.getDayEndTime(end);
            criteria.andAddTimeBetween(dayStartTime, dayEndTime);
        }
        orderExample.setOrderByClause("add_time desc");
        Page page = PageHelper.startPage(orderListDto.getStartPage(), orderListDto.getPageSize());
//  ASC是根据id 正向排序，DESC是反向排序
        PageHelper.orderBy("add_time desc");
        List<BaoxiuOrderWithBLOBs> baoxiuOrderWithBLOBs = orderMapper.selectByExampleWithBLOBs(orderExample);
        for (BaoxiuOrder baoxiuOrder : baoxiuOrderWithBLOBs) {
            OrderVo orderVo = new OrderVo();
            BeanUtils.copyProperties(baoxiuOrder, orderVo);
            orderVo.setAddTimeStr(TimeTool.dateFormat(baoxiuOrder.getAddTime()));
            orderVo.setOrderStatusStr(OrderStatusEnums.statOf(baoxiuOrder.getOrderStatus()).getEmsg());
            orderVo.setTypeStr(OrderTypeEnums.statOf(baoxiuOrder.getType()).getEmsg());
            list.add(orderVo);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());

        return vo;
    }

    /**
     * 维修单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderInfoVo orderInfo(Integer id) throws Exception {
        BaoxiuOrderWithBLOBs baoxiuOrderWithBLOBs = orderMapper.selectByPrimaryKey(id);
        if (baoxiuOrderWithBLOBs == null) {
            throw new Exception("订单不能为空");
        }
        OrderPhotoExample orderPhotoExample = new OrderPhotoExample();
        orderPhotoExample.createCriteria().andOrderIdEqualTo(id);
        List<String> applicationPhotos = new ArrayList<>();
        List<String> fixPhotos = new ArrayList<>();
        List<OrderPhotoWithBLOBs> orderPhotoWithBLOBs = orderPhotoMapper.selectByExampleWithBLOBs(orderPhotoExample);
        for (OrderPhotoWithBLOBs orderPhotoWithBLOB : orderPhotoWithBLOBs) {
            applicationPhotos.add(orderPhotoWithBLOB.getApplicationPhoto());
            fixPhotos.add(orderPhotoWithBLOB.getFixPhoto());
        }
        OrderInfoVo vo = new OrderInfoVo();
        //报修人详情
        ContractVo contractVo = new ContractVo();
        contractVo.setAddress(baoxiuOrderWithBLOBs.getAddress());
        contractVo.setContent(baoxiuOrderWithBLOBs.getContent());
        contractVo.setOrderNo(baoxiuOrderWithBLOBs.getOrderNo());
        contractVo.setContractId(baoxiuOrderWithBLOBs.getContractId());
        contractVo.setContractName(baoxiuOrderWithBLOBs.getContractName());
        contractVo.setContractPhone(baoxiuOrderWithBLOBs.getContractPhone());
        contractVo.setScore(baoxiuOrderWithBLOBs.getScore());
        contractVo.setType(baoxiuOrderWithBLOBs.getType());
        contractVo.setTypeStr(OrderTypeEnums.statOf(baoxiuOrderWithBLOBs.getType()).getEmsg());
        contractVo.setAddTimeStr(TimeTool.dateFormat(baoxiuOrderWithBLOBs.getAddTime()));
        contractVo.setPhoto(applicationPhotos);
        contractVo.setSoftName(baoxiuOrderWithBLOBs.getSoftName());
        contractVo.setFixType(baoxiuOrderWithBLOBs.getFixType());
        UserDevice userDevice = userDeviceMapper.selectByPrimaryKey(baoxiuOrderWithBLOBs.getContractId());
        contractVo.setUserDevice(userDevice);
        contractVo.setFixContent(baoxiuOrderWithBLOBs.getFixContent());
        vo.setContractVo(contractVo);

        //维修人详情
        if (baoxiuOrderWithBLOBs.getFixId() != null) {
            FixVo fixVo = new FixVo();
            fixVo.setFixId(baoxiuOrderWithBLOBs.getFixId());
            fixVo.setFixName(baoxiuOrderWithBLOBs.getFixName());
            fixVo.setPhotos(fixPhotos);
            vo.setFixVo(fixVo);
        }
        vo.setId(id);
        vo.setOrderStatus(baoxiuOrderWithBLOBs.getOrderStatus());
        return vo;
    }

    /**
     * 添加维修单
     *
     * @param addOrderDto
     */
    @Override
    public void addOrder(AddOrderDto addOrderDto) throws Exception {
        User user = new User();
        if (addOrderDto.getContractId() == null || addOrderDto.getContractId() == 0) {
            UserExample example = new UserExample();
            example.createCriteria().andAccountEqualTo(addOrderDto.getContractPhone());
            List<User> users = userMapper.selectByExample(example);
            if (users.size() > 0) {
                user = users.get(0);
            } else {
                user.setAccount(addOrderDto.getContractPhone());
                user.setUserName(addOrderDto.getContractName());
                user.setPhone(addOrderDto.getContractPhone());
                user.setAddress(addOrderDto.getAddress());
                user.setStatus(StatusEnums.NO.getEcode());
                user.setRole(2);
                user.setAddTime(new Date());
                userMapper.insert(user);
                UserDevice userDevice = new UserDevice();
                userDevice.setUid(user.getId());
                userDeviceMapper.insert(userDevice);
            }

        }else {
            user = userMapper.selectByPrimaryKey(addOrderDto.getContractId());
        }
        BaoxiuOrderWithBLOBs baoxiuOrder = new BaoxiuOrderWithBLOBs();
        baoxiuOrder.setAddress(addOrderDto.getAddress());
        baoxiuOrder.setAddTime(new Date());

        baoxiuOrder.setContractId(user.getId());
        baoxiuOrder.setContent(addOrderDto.getContent());
        baoxiuOrder.setContractName(addOrderDto.getContractName());
        baoxiuOrder.setContractPhone(addOrderDto.getContractPhone());
        baoxiuOrder.setContractId(user.getId());
        baoxiuOrder.setOrderNo(OrderNoUtil.getOrderNumber());
        baoxiuOrder.setOrderStatus(OrderStatusEnums.UN_TAKE.getEcode());
        baoxiuOrder.setStatus(StatusEnums.NO.getEcode());
        baoxiuOrder.setFixId(addOrderDto.getFixId());
        baoxiuOrder.setFixName(addOrderDto.getFixName());
        if (baoxiuOrder.getFixId() != null) {
            baoxiuOrder.setOrderStatus(OrderStatusEnums.TAKE.getEcode());
        }
        baoxiuOrder.setType(addOrderDto.getType());
        baoxiuOrder.setFixType(addOrderDto.getFixType());
        baoxiuOrder.setSoftName(addOrderDto.getSoftName());
        baoxiuOrder.setSource(addOrderDto.getSource());
        Date date = new Date();
        baoxiuOrder.setReciveTime(date);
        baoxiuOrder.setAddTime(date);
        orderMapper.insert(baoxiuOrder);
        if (addOrderDto.getApplicationPhoto() != null) {
            for (String photo : addOrderDto.getApplicationPhoto()) {
                OrderPhotoWithBLOBs orderPhoto = new OrderPhotoWithBLOBs();
                orderPhoto.setOrderId(baoxiuOrder.getId());
                orderPhoto.setAddTime(date);
                orderPhoto.setApplicationPhoto(photo);
                orderPhotoMapper.insert(orderPhoto);
            }
        }
        //todo 添加完成后异步推送订单给工程师
        if (baoxiuOrder.getFixId() != null) {
            Message message = new Message();
            message.setContent("您有新的派单,快去完成吧");
            message.setTitle("派单提醒");
            message.setUid(baoxiuOrder.getFixId());
            message.setIsRead(1);
            message.setAddTime(date);
            message.setStatus("0");
            messageMapper.insertSelective(message);
            messageService.sendMessageOrder(baoxiuOrder.getFixId());
        } else {
            // 发送新订单socket
            messageService.sendNewOrder();
        }
//        OrderCountVo orderCountVo = this.OrderCount();
//        messageService.sendCountOrder(JSONObject.toJSONString(orderCountVo));


    }

    /**
     * 人员列表
     *
     * @param fixUserListDto
     * @return
     */
    @Override
    public FixUserListVo fixUserList(FixUserListDto fixUserListDto) {
        FixUserListVo vo = new FixUserListVo();
        List<FixUserVo> list = new ArrayList<>();
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria().andRoleEqualTo(1);
        if (!StringUtils.isEmpty(fixUserListDto.getName())) {
            criteria.andUserNameLike(fixUserListDto.getName());
        }
        PageHelper.orderBy("add_time desc");
        Page page = PageHelper.startPage(fixUserListDto.getStartPage(), fixUserListDto.getPageSize());
        List<User> users = userMapper.selectByExample(example);
        for (User user : users) {
            FixUserVo fixUserVo = new FixUserVo();
            fixUserVo.setId(user.getId());
            fixUserVo.setPhone(user.getPhone());
            fixUserVo.setUserName(user.getUserName());
            fixUserVo.setStatus(user.getStatus());
            fixUserVo.setAddTimeStr(TimeTool.dateFormat(user.getAddTime()));
            MonthReportExample example1 = new MonthReportExample();
            example1.createCriteria().andUidEqualTo(user.getId()).andAddTimeBetween(TimeTool.getBeginDayOfMonth(),TimeTool.getEndDayOfMonth());
            List<MonthReport> monthReports = monthReportMapper.selectByExample(example1);
            if (monthReports.size()>0){
                fixUserVo.setFlag(true);
            }else {
                fixUserVo.setFlag(false);
            }
            list.add(fixUserVo);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 用户列表
     *
     * @param fixUserListDto
     * @return
     */
    @Override
    public FixUserListVo UserList(FixUserListDto fixUserListDto) {
        FixUserListVo vo = new FixUserListVo();
        List<FixUserVo> list = new ArrayList<>();
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria().andRoleEqualTo(2);
        if (!com.qiniu.util.StringUtils.isNullOrEmpty(fixUserListDto.getName())) {
            criteria.andUserNameLike(fixUserListDto.getName());
        }
        PageHelper.orderBy("add_time desc");
        Page page = PageHelper.startPage(fixUserListDto.getStartPage(), fixUserListDto.getPageSize());
        List<User> users = userMapper.selectByExample(example);
        for (User user : users) {
            FixUserVo fixUserVo = new FixUserVo();
            fixUserVo.setId(user.getId());
            fixUserVo.setPhone(user.getPhone());
            fixUserVo.setUserName(user.getUserName());
            fixUserVo.setStatus(user.getStatus());
            fixUserVo.setAddTimeStr(TimeTool.dateFormat(user.getAddTime()));
            list.add(fixUserVo);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 人员停用启用
     *
     * @param id
     */
    @Override
    public void delUser(Integer id) {
        User user = userMapper.selectByPrimaryKey(id);
        if (user.getStatus().equals(StatusEnums.YES.getEcode())) {
            user.setStatus(StatusEnums.NO.getEcode());
        } else {
            user.setStatus(StatusEnums.YES.getEcode());
        }
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 添加人员
     *
     * @param addUserDto
     */
    @Override
    public void addFixUser(AddFixUserDto addUserDto) throws Exception {
        UserExample example = new UserExample();
        example.createCriteria().andAddressEqualTo(addUserDto.getPhone());
        List<User> users = userMapper.selectByExample(example);
        if (users.size() > 0) {
            throw new Exception("已存在相同用户");
        }
        User user = new User();
        user.setAccount(addUserDto.getPhone());
        user.setPassword("123456");
        user.setUserName(addUserDto.getName());
        user.setPhone(addUserDto.getPhone());
        user.setStatus(StatusEnums.NO.getEcode());
        user.setAddTime(new Date());
        user.setRole(1);
        userMapper.insert(user);
    }

    /**
     * 添加用户
     *
     * @param addUserDto
     */
    @Override
    public void addUser(AddUserDto addUserDto) throws Exception {
        UserExample example = new UserExample();
        example.createCriteria().andUserNameEqualTo(addUserDto.getPhone());
        List<User> users = userMapper.selectByExample(example);
        if (users.size() > 0) {
            throw new Exception("已存在相同用户");
        }
        User user = new User();
        user.setAccount(addUserDto.getPhone());
        user.setUserName(addUserDto.getName());
        user.setPhone(addUserDto.getPhone());
        user.setAddress(addUserDto.getAddress());
        user.setStatus(StatusEnums.NO.getEcode());
        user.setAddTime(new Date());
        user.setRole(2);
        userMapper.insert(user);
        UserDevice userDevice = new UserDevice();
        userDevice.setUid(user.getId());
        userDeviceMapper.insert(userDevice);
    }

    /**
     * 报修历史
     *
     * @param UserId
     * @return
     */
    @Override
    public List<OrderHistoryVo> orderHistory(Integer UserId) {
        List<OrderHistoryVo> vos = new ArrayList<>();
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        example.createCriteria().andContractIdEqualTo(UserId);
        example.setOrderByClause("add_time desc");
        List<BaoxiuOrderWithBLOBs> baoxiuOrderWithBLOBs = orderMapper.selectByExampleWithBLOBs(example);
        for (BaoxiuOrderWithBLOBs baoxiuOrderWithBLOB : baoxiuOrderWithBLOBs) {
            OrderHistoryVo vo = new OrderHistoryVo();
            vo.setAddTimeStr(TimeTool.dateFormat(baoxiuOrderWithBLOB.getAddTime()));
            OrderPhotoExample photoExample = new OrderPhotoExample();
            photoExample.createCriteria().andOrderIdEqualTo(baoxiuOrderWithBLOB.getId());
            List<String> photos = new ArrayList<>();
            List<OrderPhotoWithBLOBs> orderPhotoWithBLOBs = orderPhotoMapper.selectByExampleWithBLOBs(photoExample);
            for (OrderPhotoWithBLOBs orderPhotoWithBLOB : orderPhotoWithBLOBs) {
                photos.add(orderPhotoWithBLOB.getApplicationPhoto());
            }
            vo.setApplicationPhoto(photos);
            vo.setContent(baoxiuOrderWithBLOB.getContent());
            vo.setFixContent(baoxiuOrderWithBLOB.getFixContent());
            vos.add(vo);
        }
        return vos;
    }

    /**
     * 设备详情
     *
     * @param userId
     * @return
     */
    @Override
    public UserDevice deviceInfo(Integer userId) {
        UserDevice userDevice = userDeviceMapper.selectByPrimaryKey(userId);
        return userDevice;
    }

    /**
     * 设备编辑
     *
     * @param userDevice
     */
    @Override
    public void deviceEdit(UserDevice userDevice) {
        UserDevice userDevice1 = userDeviceMapper.selectByPrimaryKey(userDevice.getUid());
        if (userDevice1 != null) {
            userDevice.setAddTime(new Date());
            userDeviceMapper.updateByPrimaryKeySelective(userDevice);
        } else {
            userDeviceMapper.insertSelective(userDevice);
        }

    }

    /**
     * 知识库列表
     *
     * @param knowledgeListDto
     * @return
     */
    @Override
    public KnowledgeListVo knowledgeList(KnowledgeListDto knowledgeListDto) {
        KnowledgeListVo vo = new KnowledgeListVo();
        List<KnowledgeVo> list = new ArrayList<>();
        KnowledgeExample example = new KnowledgeExample();
        KnowledgeExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(StatusEnums.NO.getEcode());
        if (!StringUtils.isEmpty(knowledgeListDto.getKeyWord())) {
            criteria.andKeyWordLike(knowledgeListDto.getKeyWord());
        }
        if (!StringUtils.isEmpty(knowledgeListDto.getType())) {
            criteria.andTypeEqualTo(knowledgeListDto.getType());
        }
        PageHelper.orderBy("add_time desc");
        Page page = PageHelper.startPage(knowledgeListDto.getStartPage(), knowledgeListDto.getPageSize());
        List<Knowledge> knowledges = knowledgeMapper.selectByExampleWithBLOBs(example);
        for (Knowledge knowledge : knowledges) {
            KnowledgeVo knowledgeVo = new KnowledgeVo();
            if (knowledge.getResult().length() >= 19) {
                knowledgeVo.setContent(knowledge.getResult().substring(0, 19) + "...");
            } else {
                knowledgeVo.setContent(knowledge.getResult());
            }
            knowledgeVo.setContentInfo(knowledge.getResult());
            knowledgeVo.setId(knowledge.getId());
            knowledgeVo.setTypeStr(KnowledgeTypeEnums.statOf(knowledge.getType()).getEmsg());
            knowledgeVo.setStatus(knowledge.getStatus());
            knowledgeVo.setKeyWord(knowledge.getKeyWord());
            list.add(knowledgeVo);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 添加知识库
     *
     * @param knowledgeListDto
     */
    @Override
    public void knowledgeAdd(KnowledgeAddDto knowledgeListDto) {
        Integer id = TokenUtil.getTokenUserId();
        Knowledge knowledge = new Knowledge();
        knowledge.setAddTime(new Date());
        knowledge.setAddUid(id);
        knowledge.setKeyWord(knowledgeListDto.getKeyWord());
        knowledge.setResult(knowledgeListDto.getContent());
        knowledge.setType(knowledgeListDto.getType());
        knowledge.setStatus(StatusEnums.NO.getEcode());
        knowledgeMapper.insert(knowledge);
    }

    /**
     * 删除知识库
     *
     * @param id
     */
    @Override
    public void knowledgeDel(Integer id) {
        Knowledge knowledge = new Knowledge();
        knowledge.setId(id);
        knowledge.setStatus(StatusEnums.YES.getEcode());
        knowledgeMapper.updateByPrimaryKeySelective(knowledge);
    }

    /**
     * 上传图片
     *
     * @param file
     * @return
     */
    @Override
    public String upLoadPhoto(MultipartFile file) {
        //构造一个带指定 Region 对象的配置类
        Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释

        UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证，然后准备上传
        String accessKey = "XXIFDSFml6O1vjrvvggHiKd7V00vuC0yP0SU6Q_4";
        String secretKey = "5SvAdizQq_dvxwV0ERHOaB_xhhp0vu-VtHyMFv5Q";
        String bucket = "baojie58";

//默认不指定key的情况下，以文件内容的hash值作为文件名
        String key = null;

        try {
//            byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
            byte[] uploadBytes = file.getBytes();
            ByteArrayInputStream byteInputStream = new ByteArrayInputStream(uploadBytes);
            Auth auth = Auth.create(accessKey, secretKey);
            String upToken = auth.uploadToken(bucket);

            try {
                Response response = uploadManager.put(byteInputStream, key, upToken, null, null);
                //解析上传成功的结果
                DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
                System.out.println(putRet.key);
                System.out.println(putRet.hash);
                return "http://cdn.fledchina.com/" + putRet.key;
            } catch (QiniuException ex) {
                Response r = ex.response;
                System.err.println(r.toString());
                try {
                    System.err.println(r.bodyString());
                } catch (QiniuException ex2) {
                    //ignore
                }
            }
        } catch (IOException ex) {
            //ignore
        }


        return null;
    }

    /**
     * 企业微信添加用户
     *
     * @param addUserDto
     */
    @Override
    public UserVo PadAddUser(AddUserDto addUserDto) {
        UserVo userVo = new UserVo();
        UserExample example = new UserExample();
        example.createCriteria().andUserNameEqualTo(addUserDto.getName());
        List<User> users = userMapper.selectByExample(example);
        if (users.size() > 0) {
            User user = users.get(0);
            user.setOpenId(addUserDto.getWeChatUid());
            user.setAddress(addUserDto.getAddress());
            user.setAccount(addUserDto.getPhone());
            userMapper.updateByPrimaryKeySelective(user);
            userVo.setUid(user.getId());
            userVo.setName(user.getUserName());
            userVo.setPhone(user.getPhone());
            userVo.setAddress(user.getAddress());
        } else {
            User user = new User();
            user.setAccount(addUserDto.getPhone());
            user.setPassword("123456");
            user.setUserName(addUserDto.getName());
            user.setPhone(addUserDto.getPhone());
            user.setStatus(StatusEnums.NO.getEcode());
            user.setAddTime(new Date());
            user.setRole(2);
            user.setAddress(addUserDto.getAddress());
            user.setOpenId(addUserDto.getWeChatUid());
            userMapper.insert(user);
            userVo.setUid(user.getId());
            userVo.setName(user.getUserName());
            userVo.setPhone(user.getPhone());
            userVo.setAddress(user.getAddress());
            //用户设备
            UserDevice userDevice = userDeviceMapper.selectByPrimaryKey(user.getId());
            if (userDevice == null) {
                UserDevice device = new UserDevice();
                device.setUid(user.getId());
                userDeviceMapper.insertSelective(device);
            }
        }
        return userVo;

    }

    /**
     * 搜索知识库
     *
     * @param searchKnowledgeDto
     * @return
     */
    @Override
    public KnowledgeListVo searchKnowledge(SearchKnowledgeDto searchKnowledgeDto) {
        KnowledgeListVo vo = new KnowledgeListVo();
        List<KnowledgeVo> list = new ArrayList<>();
        KnowledgeExample example = new KnowledgeExample();
        KnowledgeExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(StatusEnums.NO.getEcode());
        if (!StringUtils.isEmpty(searchKnowledgeDto.getKeyWord())) {
            criteria.andKeyWordLike(searchKnowledgeDto.getKeyWord());
        }
        PageHelper.orderBy("add_time desc");
        Page page = PageHelper.startPage(searchKnowledgeDto.getStartPage(), searchKnowledgeDto.getPageSize());
        List<Knowledge> knowledges = knowledgeMapper.selectByExampleWithBLOBs(example);
        for (Knowledge knowledge : knowledges) {
            KnowledgeVo knowledgeVo = new KnowledgeVo();
            if (knowledge.getResult().length() >= 19) {
                knowledgeVo.setContent(knowledge.getResult().substring(0, 19) + "...");
            } else {
                knowledgeVo.setContent(knowledge.getResult());
            }
            knowledgeVo.setContentInfo(knowledge.getResult());
            knowledgeVo.setId(knowledge.getId());
            knowledgeVo.setTypeStr(KnowledgeTypeEnums.statOf(knowledge.getType()).getEmsg());
            knowledgeVo.setStatus(knowledge.getStatus());
            list.add(knowledgeVo);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 消息列表
     *
     * @param messageListDto
     * @return
     */
    @Override
    public MessageListVo messageList(MessageListDto messageListDto) {
        MessageListVo vo = new MessageListVo();
        List<MessageVo> list = new ArrayList<>();
        Integer userId = TokenUtil.getTokenUserId();
        MessageExample example = new MessageExample();
        example.createCriteria().andUidEqualTo(userId);
        example.setOrderByClause("add_time desc");
        Page page = PageHelper.startPage(messageListDto.getStartPage(), messageListDto.getPageSize());
//  ASC是根据id 正向排序，DESC是反向排序
        PageHelper.orderBy("add_time desc");
        List<Message> messages = messageMapper.selectByExample(example);
        if (messages.size() > 0) {
            for (Message message : messages) {
                MessageVo messageVo = new MessageVo();
                messageVo.setTitle(message.getTitle());
                messageVo.setContent(message.getContent());
                messageVo.setIsRead(message.getIsRead());
                messageVo.setAddTimeStr(TimeTool.dateFormat(message.getAddTime()));
                messageVo.setId(message.getId());
                list.add(messageVo);
            }
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 读取消息
     *
     * @param id
     */
    @Override
    public void readMessage(Integer id) {
        Message message = messageMapper.selectByPrimaryKey(id);
        if (message != null) {
            message.setReadTime(new Date());
            message.setIsRead(StatusEnums.YES.getEcode());
            messageMapper.updateByPrimaryKeySelective(message);
        }
    }

    /**
     * 企业微信下单
     *
     * @param weChartAddOrderDto
     */
    @Override
    public void weChartAddOrder(WeChartAddOrderDto weChartAddOrderDto) {
        User user = null;
        if (weChartAddOrderDto.getUid() != null) {
            user = userMapper.selectByPrimaryKey(weChartAddOrderDto.getUid());
            user.setAddress(weChartAddOrderDto.getAddress());
            user.setPhone(weChartAddOrderDto.getContractPhone());
            user.setUserName(weChartAddOrderDto.getContractName());
            userMapper.updateByPrimaryKeySelective(user);
        } else {
            user = new User();
            user.setUserName(weChartAddOrderDto.getContractName());
            user.setPhone(weChartAddOrderDto.getContractPhone());
            user.setStatus(StatusEnums.NO.getEcode());
            user.setAddTime(new Date());
            user.setRole(2);
            user.setAddress(weChartAddOrderDto.getAddress());
            user.setOpenId(weChartAddOrderDto.getWeChartUid());
            userMapper.insert(user);
            //用户设备
            UserDevice userDevice = userDeviceMapper.selectByPrimaryKey(user.getId());
            if (userDevice == null) {
                UserDevice device = new UserDevice();
                device.setUid(user.getId());
                userDeviceMapper.insertSelective(device);
            }
        }

        //添加订单
        BaoxiuOrderWithBLOBs baoxiuOrder = new BaoxiuOrderWithBLOBs();
        baoxiuOrder.setAddress(weChartAddOrderDto.getAddress());
        baoxiuOrder.setAddTime(new Date());

        baoxiuOrder.setContractId(user.getId());
        baoxiuOrder.setContent(weChartAddOrderDto.getContent());
        baoxiuOrder.setContractName(weChartAddOrderDto.getContractName());
        baoxiuOrder.setContractPhone(weChartAddOrderDto.getContractPhone());
        baoxiuOrder.setOrderNo(OrderNoUtil.getOrderNumber());
        baoxiuOrder.setOrderStatus(OrderStatusEnums.UN_TAKE.getEcode());
        baoxiuOrder.setStatus(StatusEnums.NO.getEcode());
        baoxiuOrder.setSource(1);
        baoxiuOrder.setType(weChartAddOrderDto.getType());
        baoxiuOrder.setFixType(weChartAddOrderDto.getFixType());
        baoxiuOrder.setSoftName(weChartAddOrderDto.getSoftName());
        baoxiuOrder.setAddTime(new Date());
        int orderId = orderMapper.insert(baoxiuOrder);
        if (weChartAddOrderDto.getApplicationPhoto() != null) {
            for (String photo : weChartAddOrderDto.getApplicationPhoto()) {
                OrderPhotoWithBLOBs orderPhoto = new OrderPhotoWithBLOBs();
                orderPhoto.setOrderId(orderId);
                orderPhoto.setAddTime(new Date());
                orderPhoto.setApplicationPhoto(photo);
                orderPhotoMapper.insert(orderPhoto);
            }
        }
        // 发送新订单socket
        messageService.sendNewOrder();
//        OrderCountVo orderCountVo = this.OrderCount();
//        messageService.sendCountOrder(JSONObject.toJSONString(orderCountVo));
    }

    /**
     * 读取用户信息
     *
     * @param weChartUid
     * @return
     */
    @Override
    public UserInfoVo weChartUserInfo(String weChartUid) {
        UserInfoVo vo = new UserInfoVo();
        UserExample example = new UserExample();
        example.createCriteria().andOpenIdEqualTo(weChartUid);
        List<User> users = userMapper.selectByExample(example);
        if (users.size() > 0) {
            User user = users.get(0);
            vo.setId(user.getId());
            vo.setAddress(user.getAddress());
            vo.setName(user.getUserName());
            vo.setPhone(user.getPhone());
        }
        return vo;
    }

    /**
     * 解决方案列表
     *
     * @param fixListDto
     * @return
     */
    @Override
    public FixListVo fixList(FixListDto fixListDto) {
        Map<Integer, BaoxiuOrderWithBLOBs> orderMap = new HashMap<>();
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        example.createCriteria().andOrderStatusEqualTo(OrderStatusEnums.FINISH.getEcode());
        List<BaoxiuOrderWithBLOBs> baoxiuOrderWithBLOBs = orderMapper.selectByExampleWithBLOBs(example);
        for (BaoxiuOrderWithBLOBs baoxiuOrder : baoxiuOrderWithBLOBs) {
            orderMap.put(baoxiuOrder.getId(), baoxiuOrder);
        }
        List<FixList> list = new ArrayList<>();

        Page page = PageHelper.startPage(fixListDto.getStartPage(), fixListDto.getPageSize());
        PageHelper.orderBy("add_time desc");
        List<OrderFix> orderFixes = orderFixMapper.selectByExample(new OrderFixExample());
        FixListVo vo = new FixListVo();
        for (OrderFix orderFix : orderFixes) {
            FixList fixList = new FixList();
            BaoxiuOrderWithBLOBs baoxiuOrder = orderMap.get(orderFix.getOrderId());
            if (baoxiuOrder != null) {
                fixList.setFixContent(baoxiuOrder.getFixContent());
                fixList.setId(orderFix.getId());
                fixList.setSoftName(baoxiuOrder.getSoftName());
                fixList.setStatus(orderFix.getStatus());
                fixList.setAddTimeStr(TimeTool.dateFormat(orderFix.getAddTime()));
                fixList.setType(baoxiuOrder.getFixType());
                fixList.setFixName(baoxiuOrder.getFixName());
                list.add(fixList);
            }
        }
        vo.setList(list);
        vo.setTotal(list.size());
        return vo;
    }

    /**
     * 解决方案变更状态
     *
     * @param id
     */
    @Override
    public void fixOrderChangeStatus(Integer id, Integer status) {
        OrderFix orderFix = orderFixMapper.selectByPrimaryKey(id);
        if (orderFix != null) {
            orderFix.setStatus(status);
            orderFixMapper.updateByPrimaryKey(orderFix);
        }
    }

    /**
     * 未读消息数量
     *
     * @return
     */
    @Override
    public Integer unReadCount() {
        Integer userId = TokenUtil.getTokenUserId();
        MessageExample messageExample = new MessageExample();
        messageExample.createCriteria().andIsReadEqualTo(StatusEnums.NO.getEcode()).andUidEqualTo(userId);
        List<Message> messages = messageMapper.selectByExample(messageExample);
        return messages.size();
    }

    /**
     * 工程师列表
     *
     * @param name
     * @return
     */
    @Override
    public List<User> engineList(String name) {
        UserExample example = new UserExample();
        example.createCriteria().andUserNameLike(name).andRoleEqualTo(1).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<User> users = userMapper.selectByExample(example);
        return users;
    }

    /**
     * 报修单统计报表
     *
     * @param fixOrderCountDto
     * @return
     */
    @Override
    public List<FixOrderCountVo> fixOrderCount(FixOrderCountDto fixOrderCountDto) throws Exception {
        if (fixOrderCountDto.getStart() == null || fixOrderCountDto.getEnd() == null) {
            throw new Exception("查询日期不能为空");
        }
        List<FixOrderCountVo> list = new ArrayList<>();
        String start = fixOrderCountDto.getStart() + " 00:00:00";
        String end = fixOrderCountDto.getEnd() + " 23:59:59";
        //获取两个日期之间所有的日期
        Map<String, Integer> voMap = new HashMap<>();
        List<String> daysList = TimeTool.getinDays(fixOrderCountDto.getStart(), fixOrderCountDto.getEnd());
        for (String s : daysList) {
            voMap.put(s, 0);
        }
        //统计维修单总数
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = example.createCriteria();
        if (fixOrderCountDto.getFixId() != null) {
            criteria.andFixIdEqualTo(fixOrderCountDto.getFixId());
        }
        if (fixOrderCountDto.getOrderStatus() != null) {
            criteria.andOrderStatusEqualTo(fixOrderCountDto.getOrderStatus());
        }

        Date startDay = TimeTool.StringToDate(start);
        Date endDay = TimeTool.StringToDate(end);
        criteria.andAddTimeBetween(startDay, endDay);
        example.setOrderByClause("add_time ASC");
        List<SelectByCountVo> selectByCountVos = orderMapper.selectByCount(example);
        if (selectByCountVos.size() <= 0) {
            for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
                FixOrderCountVo vo = new FixOrderCountVo();
                vo.setCount(stringIntegerEntry.getValue());
                vo.setDataStr(stringIntegerEntry.getKey());
                list.add(vo);
            }
            list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));
            return list;
        }

        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
            for (SelectByCountVo selectByCountVo : selectByCountVos) {
//                FixOrderCountVo vo = new FixOrderCountVo();
//                vo.setDataStr(stringIntegerEntry.getKey());
//                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
//                    vo.setCount(selectByCountVo.getCount());
//                } else {
//                    vo.setCount(stringIntegerEntry.getValue());
//                }
//                list.add(vo);
                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
                    stringIntegerEntry.setValue(stringIntegerEntry.getValue() + 1);
                }
            }
        }
        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
            FixOrderCountVo vo = new FixOrderCountVo();
            vo.setDataStr(stringIntegerEntry.getKey());
            vo.setCount(stringIntegerEntry.getValue());
            list.add(vo);
        }
        list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));

        return list;
    }

    /**
     * 工程师统计下载
     *
     * @return
     */
    @Override
    public List<FixOrderDownLoadVo> engineerDownLoad() throws Exception {
        return null;
    }

    /**
     * 维修单列表下载
     *
     * @return
     */
    @Override
    public List<FixOrderDownLoadVo> fixOrderDownLoad() throws Exception {
        return null;
    }

    /**
     * 来源渠道统计
     *
     * @param fromCountDto
     * @return
     */
    @Override
    public List<FromCountVo> fromCount(FromCountDto fromCountDto) throws Exception {
        Date startDay = null;
        Date endDay = null;
        List<FromCountVo> list = new ArrayList<>();
        if (fromCountDto.getStart() != null || fromCountDto.getEnd() != null) {
            String start = fromCountDto.getStart() + " 00:00:00";
            String end = fromCountDto.getEnd() + " 23:59:59";
            startDay = TimeTool.StringToDate(start);
            endDay = TimeTool.StringToDate(end);
        }

        BaoxiuOrderExample example = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = example.createCriteria();
        if (startDay != null && endDay != null) {
            criteria.andAddTimeBetween(startDay, endDay);
        }
        if (fromCountDto.getFixId() != null) {
            criteria.andFixIdEqualTo(fromCountDto.getFixId());
        }
        int allCount = 0;
        List<SelectFromByCountVo> selectFromByCountVos = orderMapper.selectFromByCount(example);
        if (selectFromByCountVos.size() > 0) {
            for (SelectFromByCountVo selectFromByCountVo : selectFromByCountVos) {
                allCount = allCount + selectFromByCountVo.getCount();
                FromCountVo vo = new FromCountVo();
                vo.setCount(selectFromByCountVo.getCount());
                vo.setFrom(OrderSourceEnums.statOf(Integer.valueOf(selectFromByCountVo.getSource().toString())).getEmsg());
                list.add(vo);
            }
        }
        if (list.size() > 0) {
            for (FromCountVo vo : list) {
                vo.setPercentage(vo.getCount() / allCount * 100.00);
            }
        }
        return list;
    }

    /**
     * 平均响应时间统计
     *
     * @param fixOrderCountDto
     * @return
     */
    @Override
    public List<FixOrderCountVo> avgResponseTimeCount(FixOrderCountDto fixOrderCountDto) throws Exception {
        if (fixOrderCountDto.getStart() == null || fixOrderCountDto.getEnd() == null) {
            throw new Exception("查询日期不能为空");
        }
        List<FixOrderCountVo> list = new ArrayList<>();
        String start = fixOrderCountDto.getStart() + " 00:00:00";
        String end = fixOrderCountDto.getEnd() + " 23:59:59";
        //获取两个日期之间所有的日期
        Map<String, Integer> voMap = new HashMap<>();
        List<String> daysList = TimeTool.getinDays(fixOrderCountDto.getStart(), fixOrderCountDto.getEnd());
        for (String s : daysList) {
            voMap.put(s, 0);
        }
        //统计维修单总数
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = example.createCriteria();
        if (fixOrderCountDto.getFixId() != null) {
            criteria.andFixIdEqualTo(fixOrderCountDto.getFixId());
        }
        if (fixOrderCountDto.getOrderStatus() != null) {
            criteria.andOrderStatusEqualTo(fixOrderCountDto.getOrderStatus());
        }

        Date startDay = TimeTool.StringToDate(start);
        Date endDay = TimeTool.StringToDate(end);
        criteria.andReciveTimeBetween(startDay, endDay);
        example.setOrderByClause("add_time ASC");
        List<SelectByCountVo> selectByCountVos = orderMapper.selectAvgResponseByCount(example);
        if (selectByCountVos.size() <= 0) {
            for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
                FixOrderCountVo vo = new FixOrderCountVo();
                vo.setCount(stringIntegerEntry.getValue());
                vo.setDataStr(stringIntegerEntry.getKey());
                list.add(vo);
            }
            list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));
            return list;
        }

        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
            for (SelectByCountVo selectByCountVo : selectByCountVos) {
//                FixOrderCountVo vo = new FixOrderCountVo();
//                vo.setDataStr(stringIntegerEntry.getKey());
//                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
//                    vo.setCount(selectByCountVo.getCount());
//                } else {
//                    vo.setCount(stringIntegerEntry.getValue());
//                }
//                list.add(vo);
                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
                    stringIntegerEntry.setValue(stringIntegerEntry.getValue() + 1);
                }
            }
        }
        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
            FixOrderCountVo vo = new FixOrderCountVo();
            vo.setDataStr(stringIntegerEntry.getKey());
            vo.setCount(stringIntegerEntry.getValue());
            list.add(vo);
        }
        list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));

        return list;
////        if (selectByCountVos.size() > 0) {
////            for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
////                FixOrderCountVo vo = new FixOrderCountVo();
////                vo.setCount(stringIntegerEntry.getValue());
////                vo.setDataStr(stringIntegerEntry.getKey());
////                list.add(vo);
////            }
////            list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));
////            return list;
////        }
//
//        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
//            for (SelectByCountVo selectByCountVo : selectByCountVos) {
//                FixOrderCountVo vo = new FixOrderCountVo();
//                vo.setDataStr(stringIntegerEntry.getKey());
//                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
//                    vo.setCount(selectByCountVo.getCount());
//                } else {
//                    vo.setCount(stringIntegerEntry.getValue());
//                }
//                list.add(vo);
//            }
//        }
//        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
//            for (SelectByCountVo selectByCountVo : selectByCountVos) {
////                FixOrderCountVo vo = new FixOrderCountVo();
////                vo.setDataStr(stringIntegerEntry.getKey());
////                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
////                    vo.setCount(selectByCountVo.getCount());
////                } else {
////                    vo.setCount(stringIntegerEntry.getValue());
////                }
////                list.add(vo);
//                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
//                    stringIntegerEntry.setValue(stringIntegerEntry.getValue()+1);
//                }
//            }
//        }
//        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
//            FixOrderCountVo vo = new FixOrderCountVo();
//            vo.setDataStr(stringIntegerEntry.getKey());
//            vo.setCount(stringIntegerEntry.getValue());
//            list.add(vo);
//        }
//        list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));
//
//        return list;
    }

    /**
     * 平均完成时间统计
     *
     * @param fixOrderCountDto
     * @return
     */
    @Override
    public List<FixOrderCountVo> avgFinishTimeCount(FixOrderCountDto fixOrderCountDto) throws Exception {
        if (fixOrderCountDto.getStart() == null || fixOrderCountDto.getEnd() == null) {
            throw new Exception("查询日期不能为空");
        }
        List<FixOrderCountVo> list = new ArrayList<>();
        String start = fixOrderCountDto.getStart() + " 00:00:00";
        String end = fixOrderCountDto.getEnd() + " 23:59:59";
        //获取两个日期之间所有的日期
        Map<String, Integer> voMap = new HashMap<>();
        List<String> daysList = TimeTool.getinDays(fixOrderCountDto.getStart(), fixOrderCountDto.getEnd());
        for (String s : daysList) {
            voMap.put(s, 0);
        }
        //统计维修单总数
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = example.createCriteria();
        if (fixOrderCountDto.getFixId() != null) {
            criteria.andFixIdEqualTo(fixOrderCountDto.getFixId());
        }
        if (fixOrderCountDto.getOrderStatus() != null) {
            criteria.andOrderStatusEqualTo(fixOrderCountDto.getOrderStatus());
        }

        Date startDay = TimeTool.StringToDate(start);
        Date endDay = TimeTool.StringToDate(end);
        criteria.andFinishTimeBetween(startDay, endDay);
        example.setOrderByClause("add_time ASC");
        List<SelectByCountVo> selectByCountVos = orderMapper.selectAvgFinishByCount(example);
        if (selectByCountVos.size() <= 0) {
            for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
                FixOrderCountVo vo = new FixOrderCountVo();
                vo.setCount(stringIntegerEntry.getValue());
                vo.setDataStr(stringIntegerEntry.getKey());
                list.add(vo);
            }
            list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));
            return list;
        }

        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
            for (SelectByCountVo selectByCountVo : selectByCountVos) {
//                FixOrderCountVo vo = new FixOrderCountVo();
//                vo.setDataStr(stringIntegerEntry.getKey());
//                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
//                    vo.setCount(selectByCountVo.getCount());
//                } else {
//                    vo.setCount(stringIntegerEntry.getValue());
//                }
//                list.add(vo);
                if (selectByCountVo.getTime().equals(stringIntegerEntry.getKey())) {
                    stringIntegerEntry.setValue(stringIntegerEntry.getValue() + 1);
                }
            }
        }
        for (Map.Entry<String, Integer> stringIntegerEntry : voMap.entrySet()) {
            FixOrderCountVo vo = new FixOrderCountVo();
            vo.setDataStr(stringIntegerEntry.getKey());
            vo.setCount(stringIntegerEntry.getValue());
            list.add(vo);
        }
        list.sort(Comparator.comparing(FixOrderCountVo::getDataStr));

        return list;
    }

    /**
     * 评价统计报表
     *
     * @param fromCountDto
     * @return
     */
    @Override
    public List<ScoreCountMapVo> scoreCount(ScoreCountDto fromCountDto) throws Exception {
        Date startDay = null;
        Date endDay = null;
        List<ScoreCountMapVo> vos = new ArrayList<>();
        List<ScoreCountVo> list = new ArrayList<>();
        if (fromCountDto.getStart() != null || fromCountDto.getEnd() != null) {
            String start = fromCountDto.getStart() + " 00:00:00";
            String end = fromCountDto.getEnd() + " 23:59:59";
            startDay = TimeTool.StringToDate(start);
            endDay = TimeTool.StringToDate(end);
        }

        BaoxiuOrderExample example = new BaoxiuOrderExample();
        BaoxiuOrderExample.Criteria criteria = example.createCriteria();
        if (startDay != null && endDay != null) {
            criteria.andFinishTimeBetween(startDay, endDay);
        }
        if (fromCountDto.getFixId() != null) {
            criteria.andFixIdEqualTo(fromCountDto.getFixId());
        }
        int allCount = 0;
        List<ScoreCountVo> selectFromByCountVos = orderMapper.selectScoreByCount(example);
        if (selectFromByCountVos.size() > 0) {
            for (ScoreCountVo selectFromByCountVo : selectFromByCountVos) {
                allCount = allCount + selectFromByCountVo.getCount();
                ScoreCountVo vo = new ScoreCountVo();
                vo.setCount(selectFromByCountVo.getCount());

                if (selectFromByCountVo.getScore()==null){
                    vo.setScore(0);
                }else {
                    vo.setScore(selectFromByCountVo.getScore());
                }
                list.add(vo);
            }
        }
        Map<String, Integer> totalMap = new HashMap<>();
        totalMap.put("好评", 0);
        totalMap.put("中评", 0);
        totalMap.put("差评", 0);
        totalMap.put("未评价", 0);

        if (list.size() > 0) {
            for (ScoreCountVo vo : list) {
                if (vo.getScore()==0){
                    Integer no = totalMap.get("未评价");
                    totalMap.put("未评价", no + 1);
                    continue;
                }
                if (vo.getScore() > 0 && vo.getScore() <= 2) {
                    Integer bad = totalMap.get("差评");
                    totalMap.put("差评", bad + 1);
                    continue;
                }
                if (vo.getScore() > 2 && vo.getScore() <= 4) {
                    Integer medium = totalMap.get("中评");
                    totalMap.put("中评", medium + 1);
                    continue;
                }
                if (vo.getScore() == 5) {
                    Integer good = totalMap.get("好评");
                    totalMap.put("好评", good + 1);
                    continue;
                }
            }

            for (Map.Entry<String, Integer> stringIntegerEntry : totalMap.entrySet()) {
                ScoreCountMapVo scoreCountMapVo = new ScoreCountMapVo();

                scoreCountMapVo.setFrom(stringIntegerEntry.getKey());
                scoreCountMapVo.setCount(stringIntegerEntry.getValue());
                if (stringIntegerEntry.getValue()>0){
                    vos.add(scoreCountMapVo);
                }
            }
            for (ScoreCountMapVo vo : vos) {
                vo.setPercentage(vo.getCount() / allCount * 100);
            }

        }
        return vos;
    }

    /**
     * 用户下拉列表
     *
     * @param name
     * @return
     */
    @Override
    public List<UserListMenuVo> UserListMenu(String phone, Integer role) {
        List<UserListMenuVo> listMenuVos = new ArrayList<>();
        UserExample example = new UserExample();
        UserExample.Criteria criteria = example.createCriteria();
        if (phone!=null){
            criteria.andPhoneEqualTo(phone).andRoleEqualTo(role).andStatusEqualTo(StatusEnums.NO.getEcode());
        }else {
            criteria.andRoleEqualTo(role).andStatusEqualTo(StatusEnums.NO.getEcode());
        }
        List<User> users = userMapper.selectByExample(example);
        if (users.size() > 0) {
            for (User user : users) {
                UserListMenuVo vo = new UserListMenuVo();
                vo.setId(user.getId());
                vo.setName(user.getUserName());
                vo.setAddress(user.getAddress());
                vo.setPhone(user.getPhone());
                listMenuVos.add(vo);
            }
        }
        return listMenuVos;
    }

    /**
     * 评价已完成的订单
     *
     * @param scoreFinishOrderDto
     * @return
     */
    @Override
    public Integer scoreFinishOrder(ScoreFinishOrderDto scoreFinishOrderDto) throws Exception {
        BaoxiuOrderWithBLOBs baoxiuOrderWithBLOBs = orderMapper.selectByPrimaryKey(scoreFinishOrderDto.getId());
        if (baoxiuOrderWithBLOBs == null) {
            throw new Exception("找不到订单,参数错误");
        }
        if (!baoxiuOrderWithBLOBs.getOrderStatus().equals(OrderStatusEnums.FINISH.getEcode())) {
            throw new Exception("订单未完成,无法评价");
        }
        if (baoxiuOrderWithBLOBs.getScore() != null) {
            return baoxiuOrderWithBLOBs.getScore();
        }
        baoxiuOrderWithBLOBs.setScore(scoreFinishOrderDto.getScore());
        orderMapper.updateByPrimaryKeySelective(baoxiuOrderWithBLOBs);
        return null;
    }

    /**
     * 未处理消息订单数量
     *
     * @return
     */
    @Override
    public Integer unTakeOrderSize() {
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        example.createCriteria().andOrderStatusEqualTo(OrderStatusEnums.UN_TAKE.getEcode());
        int size = orderMapper.selectByExample(example).size();
        return size;
    }

    /**
     * 解决方案查询
     *
     * @param searchKnowledgeDto
     * @return
     */
    @Override
    public List<KnowledgeVo> searchFix(SearchKnowledgeDto searchKnowledgeDto) {
        List<KnowledgeVo> list = new ArrayList<>();
        KnowledgeExample example = new KnowledgeExample();
        KnowledgeExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(StatusEnums.NO.getEcode());
        if (!StringUtils.isEmpty(searchKnowledgeDto.getKeyWord())) {
            criteria.andKeyWordLike(searchKnowledgeDto.getKeyWord());
        }
        List<Knowledge> knowledges = knowledgeMapper.selectByExampleWithBLOBs(example);
        for (Knowledge knowledge : knowledges) {
            KnowledgeVo knowledgeVo = new KnowledgeVo();
            if (knowledge.getResult().length() >= 19) {
                knowledgeVo.setContent(knowledge.getResult().substring(0, 19) + "...");
            } else {
                knowledgeVo.setContent(knowledge.getResult());
            }
            knowledgeVo.setContentInfo(knowledge.getResult());
            knowledgeVo.setId(knowledge.getId());
            knowledgeVo.setTypeStr(KnowledgeTypeEnums.statOf(knowledge.getType()).getEmsg());
            knowledgeVo.setStatus(knowledge.getStatus());
            list.add(knowledgeVo);
        }
        return list;
    }

    /**
     * 字典列表
     *
     * @param name
     * @return
     */
    @Override
    public List<Directory> directoryList(String name) {
        DirectoryExample example = new DirectoryExample();
        DirectoryExample.Criteria criteria = example.createCriteria();
        if (name!=null&&!StringUtils.isEmpty(name)){
            criteria.andNameLike("%"+name+"%");
        }
        criteria.andParentIdEqualTo(-1).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<Directory> directories = directoryMapper.selectByExample(example);
        return directories;
    }

    /**
     * 添加字典
     *
     * @param addDirectoryDto
     */
    @Override
    public void addDirectory(AddDirectoryDto addDirectoryDto) {
        Directory directory = new Directory();
        if (addDirectoryDto.getParentId()!=null){
            directory.setParentId(addDirectoryDto.getParentId());
        }else {
            directory.setParentId(-1);
        }
        directory.setName(addDirectoryDto.getName());
        directory.setStatus(StatusEnums.NO.getEcode());
        directoryMapper.insertSelective(directory);
    }

    /**
     * 删除字典
     *
     * @param id
     */
    @Override
    public void delDirectory(Integer id) throws Exception {
        Directory directory = directoryMapper.selectByPrimaryKey(id);
        if (directory!=null){
            if (directory.getId()==1){
                throw new Exception("不可删除");
            }
            directory.setStatus(StatusEnums.YES.getEcode());
            directoryMapper.updateByPrimaryKeySelective(directory);
        }
    }

    /**
     * 子字典列表
     *
     * @param parentId
     * @return
     */
    @Override
    public List<Directory> sonDirectoryList(Integer parentId) {
        DirectoryExample example = new DirectoryExample();
        DirectoryExample.Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(parentId).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<Directory> directories = directoryMapper.selectByExample(example);
        return directories;
    }

    /**
     * 软件名称列表
     *
     * @return
     */
    @Override
    public List<String> softNameList() {
        List<String> list = new ArrayList<>();
        Directory directory = directoryMapper.selectByPrimaryKey(1);
        Integer parentId = directory.getId();
        DirectoryExample example = new DirectoryExample();
        example.createCriteria().andParentIdEqualTo(parentId);
        List<Directory> directories = directoryMapper.selectByExample(example);
        for (Directory directory1 : directories) {
            list.add(directory1.getName());
        }
        return list;
    }

    /**
     * 月报上传
     *
     * @param monthReportDto
     */
    @Override
    public void monthReport(MonthReportDto monthReportDto) throws ParseException {
        //todo 生成对应月份 已上传就不用
        Integer userId = TokenUtil.getTokenUserId();
        MonthReport monthReport = new MonthReport();
        Date date = TimeTool.StringToDate(monthReportDto.getDate());
        monthReport.setAddTime(date);
        monthReport.setMonth(TimeTool.getNowMonth());
        monthReport.setOutReport(monthReportDto.getOutReport());
        monthReport.setQuestion(monthReportDto.getQuestion());
        monthReport.setSelfEvaluation(monthReportDto.getSelfEvaluation());
        monthReport.setSuggestion(monthReportDto.getSuggestion());
        monthReport.setTotal(monthReportDto.getTotal());
        monthReport.setUid(userId);
        monthReport.setSummary(monthReportDto.getSummary());
        monthReport.setUserName(userMapper.selectByPrimaryKey(userId).getUserName());
        monthReportMapper.insertSelective(monthReport);
    }

    /**
     * 全部字典列表
     *
     * @return
     */
    @Override
    public List<AllDirectoryListVo> allDirectoryList() {
        List<AllDirectoryListVo> listVos = new ArrayList<>();

        DirectoryExample example = new DirectoryExample();
        example.createCriteria().andParentIdEqualTo(-1).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<Directory> directories = directoryMapper.selectByExample(example);
        for (Directory directory : directories) {
            AllDirectoryListVo vo = new AllDirectoryListVo();
            List<AllDirectoryListChildrenVo> childrenVoList = new ArrayList<>();
            vo.setId(directory.getId());
            vo.setName(directory.getName());
            DirectoryExample childExample = new DirectoryExample();
            childExample.createCriteria().andParentIdEqualTo(directory.getId()).andStatusEqualTo(StatusEnums.NO.getEcode());
            List<Directory> childDirectories = directoryMapper.selectByExample(childExample);
            if (childDirectories.size()>0){
                for (Directory childDirectory : childDirectories) {
                    AllDirectoryListChildrenVo childrenVo = new AllDirectoryListChildrenVo();
                    childrenVo.setId(childDirectory.getId());
                    childrenVo.setName(childDirectory.getName());
                    childrenVoList.add(childrenVo);
                }
                vo.setChildren(childrenVoList);
            }
            listVos.add(vo);
        }
        return listVos;
    }

    /**
     * 判断月报是否需要上传
     *
     * @return
     */
    @Override
    public Boolean monthReportIsUpLoad() {
        Integer userId = TokenUtil.getTokenUserId();
        MonthReportExample example = new MonthReportExample();
        example.createCriteria().andUidEqualTo(userId).andAddTimeBetween(TimeTool.getBeginDayOfMonth(),TimeTool.getEndDayOfMonth());
        List<MonthReport> monthReports = monthReportMapper.selectByExample(example);
        if (monthReports.size()>0){
            return Boolean.FALSE;
        }else {
            return Boolean.TRUE;
        }

    }

    /**
     * 查看月报
     *
     * @param uid
     * @return
     */
    @Override
    public MonthReport ShowMonthReport(Integer uid) {
        MonthReportExample example = new MonthReportExample();
        example.createCriteria().andUidEqualTo(uid);
        example.setOrderByClause("add_time desc");
        List<MonthReport> monthReports = monthReportMapper.selectByExample(example);
        if (monthReports.size()>0){
            return  monthReports.get(0);
        }
        return null;
    }

    /**
     * 完成订单/转交
     *
     * @param finishOrderDto
     */
    @Override
    @Transactional
    public void finishOrder(FinishOrderDto finishOrderDto) throws Exception {
        BaoxiuOrderWithBLOBs baoxiuOrderWithBLOBs = orderMapper.selectByPrimaryKey(finishOrderDto.getOrderId());
        //如果不是转交
        if (finishOrderDto.getReFixId() == null) {
            baoxiuOrderWithBLOBs.setFixContent(finishOrderDto.getFixContent());
            baoxiuOrderWithBLOBs.setFinishTime(new Date());
            baoxiuOrderWithBLOBs.setOrderStatus(OrderStatusEnums.FINISH.getEcode());
            if (finishOrderDto.getApplicationPhoto() != null) {
                for (String s : finishOrderDto.getApplicationPhoto()) {
                    OrderPhotoWithBLOBs photo = new OrderPhotoWithBLOBs();
                    photo.setFixPhoto(s);
                    photo.setAddTime(new Date());
                    photo.setOrderId(baoxiuOrderWithBLOBs.getId());
                    orderPhotoMapper.insert(photo);
                }
            }

        } else {
            baoxiuOrderWithBLOBs.setFixId(finishOrderDto.getReFixId());
            baoxiuOrderWithBLOBs.setFixName(finishOrderDto.getReFixName());
        }
        if (finishOrderDto.getUserDevice() != null) {
            this.deviceEdit(finishOrderDto.getUserDevice());
        }
        //录入解决方案库
        orderMapper.updateByPrimaryKeyWithBLOBs(baoxiuOrderWithBLOBs);
        OrderFix orderFix = new OrderFix();
        orderFix.setAddTime(new Date());
        orderFix.setOrderId(finishOrderDto.getOrderId());
        orderFix.setStatus(0);
        orderFixMapper.insert(orderFix);
        //todo 完成订单后异步发送评价消息
        Integer contractId = baoxiuOrderWithBLOBs.getContractId();
        User user = userMapper.selectByPrimaryKey(contractId);
        if (user == null) {
            throw new Exception("参数错误");
        }
//        String openId = user.getOpenId();
        if (finishOrderDto.getReFixId() != null) {
            // todo 发送消息
        }


    }

    /**
     * 接单
     *
     * @param id
     */
    @Override
    @Transactional
    public void receiving(Integer id) throws Exception {
        Integer userId = TokenUtil.getTokenUserId();
        User user = userMapper.selectByPrimaryKey(userId);
        BaoxiuOrderWithBLOBs baoxiuOrderWithBLOBs = orderMapper.selectByPrimaryKey(id);
        if (baoxiuOrderWithBLOBs == null || !baoxiuOrderWithBLOBs.getOrderStatus().equals(OrderStatusEnums.UN_TAKE.getEcode())) {
            throw new Exception("该单已被接单");
        }
        BaoxiuOrderExample example = new BaoxiuOrderExample();
        example.createCriteria().andFixIdEqualTo(userId).andOrderStatusEqualTo(OrderStatusEnums.TAKE.getEcode());
        List<BaoxiuOrder> baoxiuOrders = orderMapper.selectByExample(example);
        if (baoxiuOrders.size() > 0) {
            throw new Exception("请先完成上一单后方可接单");
        }
        baoxiuOrderWithBLOBs.setOrderStatus(OrderStatusEnums.TAKE.getEcode());
        baoxiuOrderWithBLOBs.setFixId(userId);
        baoxiuOrderWithBLOBs.setFixName(user.getUserName());
        orderMapper.updateByPrimaryKeyWithBLOBs(baoxiuOrderWithBLOBs);

        // 发送新订单socket
        messageService.sendNewOrder();
    }


}